﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EntitiesLayer.Entities;
using DataBaseLayer;
using TSUILayer.Views.PopUps;
using CommonLayer;
using EntitiesLayer.ViewModels;
using System.Data.Linq;
using TSUILayer.Views.Reports;

namespace TSUILayer.Views.Sales
{
    /// <summary>
    /// Interaction logic for SellSpares.xaml
    /// </summary>
    public partial class SellSpares : Page
    {
        #region Private Variables
        
        DataLayer data = null;
        IEnumerable<DDBinding> _autoSource = null;
        SALES_INVOICE SpareSaleInvoice = new SALES_INVOICE();
        SPARE_PURCHASES_SALE deletedObj = null;
        decimal _SpareTotalAmount = 0;
        decimal _lubricantTotal = 0;
        decimal _spareTotalVat = 0;
        decimal _lubTotalVat = 0;

        #endregion


        public SellSpares()
        {
            InitializeComponent();
            data = DataLayer.Instance;
            lstSugesstions.DisplayMemberPath = "Name";
            lstSugesstions.SelectedValuePath = "Id";
            btnSaveAllSparesPurchase.IsEnabled = false;
            btnUpdate.IsEnabled = false;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            dataGridInvoices.ItemsSource = data.GetAll<SALES_INVOICE>(s => s.SELL_TYPE == data.GetMasterId(CommonLayer.TYPE.SPARE.ToString()))
                .Select(s => new InvoiceViewModel()
            {
                InvoiceNumber = s.SALES_INVOICE_ID.ToString(),
                InvoiceDate = s.INVOICE_DATE.Value.ToString("dd/MM/yyyy"),
                GrandTotal = s.INVOICE_GRANDTOTAL.Value
            });

            radioButtonSpares.IsChecked = true;
            cmbSupplier.ItemsSource = data.GetAllSuppliers(CommonLayer.TYPE.SPARE);
            cmbCustomer.ItemsSource = data.GetAllCustomers();
            lblInvoiceNo.Content = data.GetAll<SALES_INVOICE>().Count > 0 ? data.GetAll<SALES_INVOICE>().Max(s => s.SALES_INVOICE_ID) + 1 : 1;
        }

        private void btnAddSpares_Click(object sender, RoutedEventArgs e)
        {
            SPARE_PURCHASES_SALE spareSale = new SPARE_PURCHASES_SALE();

            if (ValidateMandatoryFields())
                return;

            spareSale.SUPPLIER_ID = Convert.ToInt32(cmbSupplier.SelectedValue);
            spareSale.SPARE_PART_ID = Convert.ToInt32(lstSugesstions.SelectedValue);
            spareSale.SUPPLIER = data.GetById<SUPPLIER>(s => s.SUPPLIER_ID == spareSale.SUPPLIER_ID);
            spareSale.SPARE_PART = data.GetById<SPARE_PART>(s => s.SPARE_PART_ID == spareSale.SPARE_PART_ID);
            spareSale.QUANTITY = Convert.ToInt32(txtQuantity.Text);
            spareSale.SUB_TOTAL = Convert.ToDecimal(txtSubTotal.Text);
            spareSale.SPARE_UNIT_COST = Convert.ToDecimal((cmbUnitCost.SelectedItem as StockViewModel).UnitCost);
            spareSale.VAT_PERCENT = Convert.ToDecimal(lblVatInPercentage.Content);
            SpareSaleInvoice.SPARE_PURCHASES_SALEs.ListChanged += new System.ComponentModel.ListChangedEventHandler(SPARE_PURCHASES_SALEs_ListChanged);
            SpareSaleInvoice.SPARE_PURCHASES_SALEs.Add(spareSale);
            spareSale.SPARE_TYPE = data.GetMasterId((radioButtonLubricants.IsChecked.Value ? CommonLayer.SPARETYPE.LUBRICANT : CommonLayer.SPARETYPE.ITEMS).ToString());
            spareSale.TRANSACTION_TYPE = data.GetMasterId(CommonLayer.TRANSACTIONTYPE.SALE.ToString());
            gridSpares.ItemsSource = SpareSaleInvoice.SPARE_PURCHASES_SALEs.ToList();
            lblTotalAmount.Content = (_SpareTotalAmount + _lubricantTotal).ToString();
            lblTotalAmount.Visibility = Visibility.Visible;
            spareSale.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(spareSale_PropertyChanged);
            gridSpares.Items.Refresh();
            ClearControls();
            SetDiscountVatAndTotalAmount();
            if (dataGridInvoices.SelectedItem == null)
                btnSaveAllSparesPurchase.IsEnabled = true;
            else
                btnUpdate.IsEnabled = true;
        }

        void SPARE_PURCHASES_SALEs_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
        {
            CalcSubTotal(sender as EntitySet<SPARE_PURCHASES_SALE>);
        }

        void spareSale_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("QUANTITY") && gridSpares.ItemsSource != null)
            {
                var currentObj = sender as SPARE_PURCHASES_SALE;
                currentObj.SUB_TOTAL = currentObj.SPARE_UNIT_COST * currentObj.QUANTITY;
                CalcSubTotal(gridSpares.ItemsSource.Cast<SPARE_PURCHASES_SALE>());
            }
        }

        private void CalcSubTotal(IEnumerable<SPARE_PURCHASES_SALE> source)
        {
            var result = source.GroupBy(s => s.VAT_PERCENT, (a, b) => new { vat = a, total = b.Sum(s => s.SUB_TOTAL) });
            _lubTotalVat = _spareTotalVat = _lubricantTotal = _SpareTotalAmount = 0;
            foreach (var item in result)
            {
                if (item.vat == decimal.Parse("5.5"))
                {
                    _SpareTotalAmount = item.total;
                    _spareTotalVat = (item.total * item.vat)/Convert.ToDecimal(105.5);
                }
                else
                {
                    _lubricantTotal = item.total;
                    _lubTotalVat = (item.total * item.vat) / Convert.ToDecimal(114.5);
                }
            }
            lblTotalAmount.Content = getGrandTotalInvoice();
            SetDiscountVatAndTotalAmount();
        }

        private void ClearControls()
        {
            Common.ClearAllControls<TextBox>(gridControls);
            Common.ClearAllControls<ComboBox>(gridControls, 2);
        }

        private bool ValidateMandatoryFields()
        {
            if (Convert.ToInt32(txtQuantity.Text) > (int)cmbUnitCost.SelectedValue)
            {
                MessageBox.Show("Quantity is more than available Stock.");
                return true;
            }
            if (txtSparePartCode.Text != string.Empty || txtPartCodeDescription.Text != string.Empty || txtQuantity.Text != string.Empty || txtSubTotal.Text.ToString() != string.Empty || cmbSupplier.Text != string.Empty)
                return false;
            else
            {
                MessageBox.Show("Please Fill the Mandatory Fields");
                return true;
            }
        }

        public void SetTotalAmount(object sender, RoutedEventArgs e)
        {
            lblGrandTotal.Content = (getGrandTotalInvoice() - (string.IsNullOrEmpty(txtDiscount.Text) ? 0 : Convert.ToDecimal(txtDiscount.Text))).ToString();
        }

        public void SetSubTotal(object sender, RoutedEventArgs e)
        {
            StockViewModel stockObj = null;
            if ((stockObj = cmbUnitCost.SelectedItem as StockViewModel) is StockViewModel)
            {
                txtSubTotal.Text = (Convert.ToDecimal(stockObj.UnitCost) * Convert.ToDecimal(string.IsNullOrEmpty(txtQuantity.Text) ? null : txtQuantity.Text)).ToString();
            }
        }

        private void btnSaveAllSparesPurchase_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Please verify the Purchase Invoice by Clicking View Invoice Once. Because Wrong entry might consume extra efforts or Loss of Data for Future Edit. You want to Proceed? ", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);

            if (result.Equals(MessageBoxResult.No))
                return;
            SpareSaleInvoice.CUSTOMER = data.GetById<CUSTOMER>(s => s.CUSTOMER_ID == Convert.ToInt32(cmbCustomer.SelectedValue));
            SpareSaleInvoice.INVOICE_DATE = dateTimeInvoiceDate.SelectedDate.Value;
            SpareSaleInvoice.INVOICE_DISCOUNT = string.IsNullOrEmpty(txtDiscount.Text) ? 0 : Convert.ToDecimal(txtDiscount.Text);
            SpareSaleInvoice.INVOICE_GRANDTOTAL = Convert.ToDecimal(lblGrandTotal.Content);
            SpareSaleInvoice.SELL_TYPE = data.GetMasterId(CommonLayer.TYPE.SPARE.ToString());
            if (!string.IsNullOrEmpty(txtAmountPaid.Text))
            {
                BALANCE balancePaid = new BALANCE()
                {
                    AMOUNT_PAID = Convert.ToDecimal(txtAmountPaid.Text),
                    PAID_DATE = dateTimeInvoiceDate.SelectedDate.Value
                };
                SpareSaleInvoice.BALANCEs.Add(balancePaid);
            }
            if (dataGridInvoices.SelectedItem == null)
            {
                data.Insert<SALES_INVOICE>(SpareSaleInvoice);
                MessageBox.Show("Spares Details Saved Successfully");
            }
            gridSpares.ItemsSource = null;
            this.NavigationService.Refresh();
            SampleReportViewer rv = new SampleReportViewer();
            rv.RenderReportViewer(SpareSaleInvoice.SALES_INVOICE_ID.ToString(),"SpareInvoice");
            rv.Show();
        }

        #region - UI Validations.
        private void NumericOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            e.Handled = IsTextNumeric(e.Text);
        }
        private static bool IsTextNumeric(string str)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^0-9]");
            return reg.IsMatch(str);

        }


        private void AlphabetOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            e.Handled = IsAlphabet(e.Text);
        }
        private static bool IsAlphabet(string str)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^A-Za-z]");
            return reg.IsMatch(str);
        }


        private void FloatingPointOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            e.Handled = IsFloatingPointvalue(e.Text);
        }
        private static bool IsFloatingPointvalue(string str)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^0-9.-]");
            return reg.IsMatch(str);
        }


        private void AlphaNumerictOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            e.Handled = IsAlphaNumeric(e.Text);
        }
        private static bool IsAlphaNumeric(string str)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9]");
            return reg.IsMatch(str);
        }
        #endregion - UI Validations.

        private void radioButtonLubricants_Checked(object sender, RoutedEventArgs e)
        {
            radioButtonSpares.IsChecked = false;
            lblVatInPercentage.Content = "14.5";
            if (!string.IsNullOrEmpty(txtSubTotal.Text))
                SetDiscountVatAndTotalAmount();
            ClearControls();

        }

        private void txtExpOnTotalAmount_KeyUp(object sender, KeyEventArgs e)
        {
            SetDiscountVatAndTotalAmount();
        }

        private void SetDiscountVatAndTotalAmount()
        {
            if (radioButtonLubricants.IsChecked == true || radioButtonSpares.IsChecked == true)
            {
                lblVatAmount.Content = getVatAmount().ToString();
                lblGrandTotal.Content = getGrandTotalInvoice().ToString();
            }
            else
            {
                MessageBox.Show("Please select the Radio Buttons");
            }
        }

        private decimal getGrandTotalInvoice()
        {
            return decimal.Round(_SpareTotalAmount + _lubricantTotal, 2);
        }

        private decimal getVatAmount()
        {            
            return decimal.Round((_spareTotalVat + _lubTotalVat), 2);
        }

        private string getDiscountAmount()
        {
            double discountAmount = 0;
            return discountAmount.ToString();
        }

        private void radioButtonSpares_Checked(object sender, RoutedEventArgs e)
        {
            radioButtonLubricants.IsChecked = false;
            lblVatInPercentage.Content = "5.5";
            if (!string.IsNullOrEmpty(txtSubTotal.Text))
                SetDiscountVatAndTotalAmount();
            ClearControls();
        }

        private void btnSearchInvoice_Click(object sender, RoutedEventArgs e)
        {
            dataGridInvoices.ItemsSource = data.GetAll<SALES_INVOICE>(s => s.SELL_TYPE == data.GetMasterId(CommonLayer.TYPE.SPARE.ToString()))
                .Where(s => s.SALES_INVOICE_ID == Convert.ToInt32(txtInvoiceSearch.Text))
               .Select(s => new InvoiceViewModel()
               {
                   InvoiceNumber = s.SALES_INVOICE_ID.ToString(),
                   InvoiceDate = s.INVOICE_DATE.Value.ToString("dd/MM/yyyy"),
                   GrandTotal = s.INVOICE_GRANDTOTAL.Value
               });
        }

        private void gridSparesAdded_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {

        }

        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {
            SpareSaleInvoice.INVOICE_GRANDTOTAL = Convert.ToDecimal(lblGrandTotal.Content);
            btnSaveAllSparesPurchase_Click(sender, e);
            if (deletedObj != null)
                data.Delete<SPARE_PURCHASES_SALE>(deletedObj);
            deletedObj = null;
            data.Update<SALES_INVOICE>();
            MessageBox.Show("Spares Details Updated Successfully");
        }

        private void btnViewInvoice_Click(object sender, RoutedEventArgs e)
        {

        }

        private void cmbSupplier_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _autoSource = data.GetAll<SPARE_PART>(s => s.MASTER.MASTER_VALUE.Equals(CommonLayer.STATUS.ACTIVE))
               .Join(data.GetAll<SPARE_PURCHASES_SALE>(s => s.SUPPLIER_ID == Convert.ToInt32(cmbSupplier.SelectedValue)), sp => sp.SPARE_PART_ID, sr => sr.SPARE_PART_ID, (a, b) => a)
               .GroupBy(s => s.SPARE_PART_CODE, (a, b) => new CommonLayer.DDBinding() { Id = b.First().SPARE_PART_ID, Name = a });
            txtPartCodeDescription.Text = string.Empty;
            cmbUnitCost.Text = string.Empty;
            txtSubTotal.Text = string.Empty;
            txtQuantity.Text = string.Empty;
            txtSparePartCode.Text = string.Empty;
        }

        private void txtSparePartCode_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_autoSource != null)
            {
                var result = _autoSource.Where(s => s.Name.ToLower().Contains(txtSparePartCode.Text.ToLower()) && !string.IsNullOrEmpty(txtSparePartCode.Text)).Select(s => s);
                lstSugesstions.Visibility = result.Count() <= 0 ? Visibility.Collapsed : Visibility.Visible;
                lstSugesstions.ItemsSource = result;
            }
        }

        private void lstSugesstions_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            txtSparePartCode.TextChanged -= new TextChangedEventHandler(txtSparePartCode_TextChanged);
            if (lstSugesstions.SelectedValue != null)
            {
                txtSparePartCode.Text = (lstSugesstions.SelectedItem as DDBinding).Name;
                var result = data.GetStock(Convert.ToInt32(cmbSupplier.SelectedValue), Convert.ToInt32(lstSugesstions.SelectedValue));
                if (result.Count > 0)
                {
                    txtPartCodeDescription.Text = result.First(s => s != null).Description;
                    cmbUnitCost.ItemsSource = result.Where(s => s.Stock > 0);
                }
            }
            lstSugesstions.Visibility = Visibility.Collapsed;
            txtSparePartCode.TextChanged += new TextChangedEventHandler(txtSparePartCode_TextChanged);
        }

        private void dataGridInvoices_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            var selectedRow = dataGridInvoices.CurrentItem as InvoiceViewModel;
            if (selectedRow is InvoiceViewModel)
            {
                SpareSaleInvoice = data.GetById<SALES_INVOICE>(s => s.SALES_INVOICE_ID == Convert.ToInt32(selectedRow.InvoiceNumber));
                lblInvoiceNo.Content = SpareSaleInvoice.SALES_INVOICE_ID;
                cmbCustomer.Text = SpareSaleInvoice.CUSTOMER.CUSTOMER_NAME;
                dateTimeInvoiceDate.SelectedDate = SpareSaleInvoice.INVOICE_DATE;
                SpareSaleInvoice.SPARE_PURCHASES_SALEs.ListChanged += new System.ComponentModel.ListChangedEventHandler(SPARE_PURCHASES_SALEs_ListChanged);
                var result = SpareSaleInvoice.SPARE_PURCHASES_SALEs.ToList();
                result.ForEach(s => s.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(spareSale_PropertyChanged));
                gridSpares.ItemsSource = result;
                if (SpareSaleInvoice.SPARE_PURCHASES_SALEs.Count > 0)
                    btnUpdate.IsEnabled = true;
            }
            CalcSubTotal(gridSpares.ItemsSource.Cast<SPARE_PURCHASES_SALE>());
        }

        private void gridSpares_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            var dataGrid = sender as DataGrid;
            if (e.Key == Key.Delete)
            {
                var currentObj = dataGrid.CurrentItem as SPARE_PURCHASES_SALE;
                if (currentObj.SPARE_ID != 0)
                {
                    deletedObj = data.GetById<SPARE_PURCHASES_SALE>(s => s.SPARE_ID == currentObj.SPARE_ID);                   
                }
                SpareSaleInvoice.SPARE_PURCHASES_SALEs.Remove((dataGrid.CurrentItem as SPARE_PURCHASES_SALE));
            }
            if (SpareSaleInvoice.SPARE_PURCHASES_SALEs.Count <= 0)
                btnSaveAllSparesPurchase.IsEnabled = false;
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Refresh();
        }

        private void btnInvoice_Click(object sender, RoutedEventArgs e)
        {
            SampleReportViewer rv = new SampleReportViewer();
            rv.RenderReportViewer(txtInvoiceSearch.Text, "SpareInvoice");
            rv.Show();
        }
    }
}
